package com.ebuildy.datamanagement
{
	import com.adobe.cairngorm.control.CairngormEvent;
	
	import mx.collections.ArrayCollection;
	import mx.core.ClassFactory;
	import mx.events.CollectionEvent;
	import mx.events.CollectionEventKind;
	import mx.events.PropertyChangeEvent;

	public class ServerArrayCollection extends ArrayCollection
	{
		public var modelName:String;
		
		static public const CREATE:String = "create";
		static public const READ:String = "read";
		static public const UPDATE:String = "update";
		static public const DELETE:String = "delete";
		
		static public const CRUDMODEL_EVENT:String = "crudmodelevent";
		
		public var connect:Boolean = true;
		
		public var voClassFactory:ClassFactory;
				
		public function ServerArrayCollection(modelName:String,voClassFactory:Class = null)
		{
			this.modelName = modelName;
			
			if (voClassFactory)
			{
				this.voClassFactory = new ClassFactory(voClassFactory);
			}
			
			this.addEventListener(CollectionEvent.COLLECTION_CHANGE, onCollectionChange);
		}
		
		public function getItemByField(field:String,value:Object):Object
		{
			for each (var item:Object in this)
			{
				if (item.hasOwnProperty(field) && item[field] == value)
				{
					return item;
				}
			}
			
			return null;
		}
		
		public function addItem2(item:Object, callback:Function):void
		{
			this.connect = false;
			
			super.addItem(item);
			
			dispatchCRUDModelEvent(CREATE,item,callback);
			
			this.connect = true;
		}
				
		public function mergeArray(value:Array):void
		{
			for each (var item:Object in value)
			{
				this.addItem(item);
			}
		}
		
		public function removeItem(item:Object):void
		{
			if (this.contains(item))
			{
				this.removeItemAt(this.getItemIndex(item));
			}
		}
		
		
		public function read(force:Boolean = false):void
		{
			if (force || super.length == 0)
			{
				dispatchCRUDModelEvent(READ);
			}
		}
		
		public function execute(method:String,data:Object = null,callback:Function = null):void
		{
			var event:CairngormEvent = new CairngormEvent(CRUDMODEL_EVENT);
			
			if (data == null)
			{
				data = new Object();
			}
			
			data['model'] = this;
			data['operation'] = method;
			data['callback'] = callback;
			
			event.data = data;		
			
			event.dispatch();
		}
		
		private function onCollectionChange(e:CollectionEvent):void
		{
			if (this.connect)
			{
				for each (var item:Object in e.items)
				{
					if (e.kind == CollectionEventKind.ADD)
					{
						dispatchCRUDModelEvent(CREATE,item);
					}
					else if (e.kind == CollectionEventKind.UPDATE)
					{
						dispatchCRUDModelEvent(UPDATE,PropertyChangeEvent(item).source);
					}
					else if (e.kind == CollectionEventKind.REMOVE)
					{
						dispatchCRUDModelEvent(DELETE,item);
					}
				}
			}
		}
				
		private function dispatchCRUDModelEvent(operation:String,item:Object = null, callback:Function = null):void
		{
			var event:CairngormEvent = new CairngormEvent(CRUDMODEL_EVENT);
			
			event.data = {'model':this,'operation':operation,'item':item, 'callback':callback};
			
			event.dispatch();
		}
		
	}
}